<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Go笔记 | lilei</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/images/icons/logo.png">
    <link rel="apple-touch-icon" href="/images/icons/logo.png">
    <link rel="manifest" href="/manifest.json">
    <script type="text/javascript" src="/assets/js/load.js"></script>
    <meta name="description" content="个人网站">
    <meta name="twitter:title" content="Go笔记">
    <meta name="twitter:description" content="">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:url" content="http://www.lileiblog.xyz/Form/Go%E7%AC%94%E8%AE%B0.html">
    <meta property="og:type" content="article">
    <meta property="og:title" content="Go笔记">
    <meta property="og:description" content="">
    <meta property="og:url" content="http://www.lileiblog.xyz/Form/Go%E7%AC%94%E8%AE%B0.html">
    <meta property="og:site_name" content="lilei">
    <meta itemprop="name" content="Go笔记">
    <meta itemprop="description" content="">
    <meta name="theme-color" content="#3eaf7c">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="msapplication-TileImage" content="/images/icons/logo.png">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="keywords" content="lilei,vue,vuepress,vuepress-theme,theme,主题,vuepress主题,blog
        ,vuepress-blog,java,python,shell,sql,golang,script,shell script,nginx,windows,去广告,androd,google drive
        ,one drive,idea,eclipse,git,小程序">
    <meta name="referrer" content="never">
    
    <link rel="preload" href="/assets/css/0.styles.8932179b.css" as="style"><link rel="preload" href="/assets/js/app.269009d6.js" as="script"><link rel="preload" href="/assets/js/3.974b9720.js" as="script"><link rel="preload" href="/assets/js/10.5915e99b.js" as="script"><link rel="prefetch" href="/assets/js/11.ff732762.js"><link rel="prefetch" href="/assets/js/12.8bb86d91.js"><link rel="prefetch" href="/assets/js/13.18bde5b0.js"><link rel="prefetch" href="/assets/js/14.314fae34.js"><link rel="prefetch" href="/assets/js/15.0a4ff48f.js"><link rel="prefetch" href="/assets/js/16.ffaf1503.js"><link rel="prefetch" href="/assets/js/17.49a31a6e.js"><link rel="prefetch" href="/assets/js/18.7e6443bf.js"><link rel="prefetch" href="/assets/js/19.6880cc9a.js"><link rel="prefetch" href="/assets/js/20.1fb3f255.js"><link rel="prefetch" href="/assets/js/21.0cd39eea.js"><link rel="prefetch" href="/assets/js/22.392d85cb.js"><link rel="prefetch" href="/assets/js/23.f50adb15.js"><link rel="prefetch" href="/assets/js/24.43e324e1.js"><link rel="prefetch" href="/assets/js/25.e3663205.js"><link rel="prefetch" href="/assets/js/26.da141fb8.js"><link rel="prefetch" href="/assets/js/27.6c05235a.js"><link rel="prefetch" href="/assets/js/28.c124245a.js"><link rel="prefetch" href="/assets/js/29.d185870d.js"><link rel="prefetch" href="/assets/js/30.8587d422.js"><link rel="prefetch" href="/assets/js/31.dc382b56.js"><link rel="prefetch" href="/assets/js/32.20ba32e9.js"><link rel="prefetch" href="/assets/js/33.6ecd7de9.js"><link rel="prefetch" href="/assets/js/34.2b91c13a.js"><link rel="prefetch" href="/assets/js/35.66ed0733.js"><link rel="prefetch" href="/assets/js/36.ce7bca84.js"><link rel="prefetch" href="/assets/js/37.d00bb5ac.js"><link rel="prefetch" href="/assets/js/38.c3ecbb6f.js"><link rel="prefetch" href="/assets/js/39.308f4175.js"><link rel="prefetch" href="/assets/js/4.520f6ecc.js"><link rel="prefetch" href="/assets/js/40.f4b98bc2.js"><link rel="prefetch" href="/assets/js/41.95fae64f.js"><link rel="prefetch" href="/assets/js/42.fe4f877b.js"><link rel="prefetch" href="/assets/js/43.ca8f222e.js"><link rel="prefetch" href="/assets/js/44.4d4ee79e.js"><link rel="prefetch" href="/assets/js/45.79178b33.js"><link rel="prefetch" href="/assets/js/46.c3817d0b.js"><link rel="prefetch" href="/assets/js/47.b8252443.js"><link rel="prefetch" href="/assets/js/48.df9d5d3b.js"><link rel="prefetch" href="/assets/js/49.d812fdb2.js"><link rel="prefetch" href="/assets/js/5.f1a24a16.js"><link rel="prefetch" href="/assets/js/50.55cfcaa8.js"><link rel="prefetch" href="/assets/js/51.b8608b02.js"><link rel="prefetch" href="/assets/js/52.52c5e00d.js"><link rel="prefetch" href="/assets/js/53.3a9bd5fb.js"><link rel="prefetch" href="/assets/js/54.a4240c13.js"><link rel="prefetch" href="/assets/js/55.01c4b876.js"><link rel="prefetch" href="/assets/js/56.f29549a3.js"><link rel="prefetch" href="/assets/js/57.01438a04.js"><link rel="prefetch" href="/assets/js/58.29bb4626.js"><link rel="prefetch" href="/assets/js/59.e8b89408.js"><link rel="prefetch" href="/assets/js/6.8c478b39.js"><link rel="prefetch" href="/assets/js/60.bedb5381.js"><link rel="prefetch" href="/assets/js/61.bdfbe584.js"><link rel="prefetch" href="/assets/js/62.cb825d1a.js"><link rel="prefetch" href="/assets/js/63.a9516572.js"><link rel="prefetch" href="/assets/js/64.aa854ed7.js"><link rel="prefetch" href="/assets/js/65.285f883d.js"><link rel="prefetch" href="/assets/js/66.12849f37.js"><link rel="prefetch" href="/assets/js/67.c18b00e4.js"><link rel="prefetch" href="/assets/js/68.fa59daa9.js"><link rel="prefetch" href="/assets/js/69.e9d5dda4.js"><link rel="prefetch" href="/assets/js/7.cfb0d0ea.js"><link rel="prefetch" href="/assets/js/70.db126cce.js"><link rel="prefetch" href="/assets/js/71.6acb04cd.js"><link rel="prefetch" href="/assets/js/72.7ff0ab11.js"><link rel="prefetch" href="/assets/js/73.9a66da79.js"><link rel="prefetch" href="/assets/js/74.0a38a030.js"><link rel="prefetch" href="/assets/js/75.7b32dbb3.js"><link rel="prefetch" href="/assets/js/8.cb9c08e5.js"><link rel="prefetch" href="/assets/js/9.ad652cfe.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.110a1065.js">
    <link rel="stylesheet" href="/assets/css/0.styles.8932179b.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/images/icons/logo.png" alt="lilei" class="logo"> <span class="site-name can-hide">lilei</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/Form/" class="nav-link router-link-active">
  Form
</a></div><div class="nav-item"><a href="/IDE/" class="nav-link">
  IDE
</a></div><div class="nav-item"><a href="/Java/" class="nav-link">
  Java
</a></div><div class="nav-item"><a href="/Other/" class="nav-link">
  Other
</a></div><div class="nav-item"><a href="/Python/" class="nav-link">
  Python
</a></div><div class="nav-item"><a href="/SQL/" class="nav-link">
  SQL
</a></div><div class="nav-item"><a href="/Shell/" class="nav-link">
  Shell
</a></div><div class="nav-item"><a href="/System/" class="nav-link">
  System
</a></div> <a href="https://github.com/woytu/notes-vuepress" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/Form/" class="nav-link router-link-active">
  Form
</a></div><div class="nav-item"><a href="/IDE/" class="nav-link">
  IDE
</a></div><div class="nav-item"><a href="/Java/" class="nav-link">
  Java
</a></div><div class="nav-item"><a href="/Other/" class="nav-link">
  Other
</a></div><div class="nav-item"><a href="/Python/" class="nav-link">
  Python
</a></div><div class="nav-item"><a href="/SQL/" class="nav-link">
  SQL
</a></div><div class="nav-item"><a href="/Shell/" class="nav-link">
  Shell
</a></div><div class="nav-item"><a href="/System/" class="nav-link">
  System
</a></div> <a href="https://github.com/woytu/notes-vuepress" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Form</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/Form/" aria-current="page" class="sidebar-link">介绍</a></li><li><a href="/Form/Go操作Windows.html" class="sidebar-link">Go操作Windows</a></li><li><a href="/Form/Go爬虫.html" class="sidebar-link">Go爬虫</a></li><li><a href="/Form/Go笔记.html" class="active sidebar-link">Go笔记</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#flag" class="sidebar-link">Flag</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#字符串" class="sidebar-link">字符串</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#io操作" class="sidebar-link">IO操作</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#异常和恢复" class="sidebar-link">异常和恢复</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#http" class="sidebar-link">HTTP</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#作业调度" class="sidebar-link">作业调度</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#进程线程协程" class="sidebar-link">进程线程协程</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#orm" class="sidebar-link">ORM</a></li><li class="sidebar-sub-header"><a href="/Form/Go笔记.html#daemon" class="sidebar-link">Daemon</a></li></ul></li><li><a href="/Form/Go编译打包.html" class="sidebar-link">Go编译打包</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="go笔记"><a href="#go笔记" class="header-anchor">#</a> Go笔记</h1> <p></p><div class="table-of-contents"><ul><li><a href="#flag">Flag</a></li><li><a href="#字符串">字符串</a><ul><li><a href="#strings包api">strings包API</a></li><li><a href="#字符串拼接">字符串拼接</a></li></ul></li><li><a href="#io操作">IO操作</a><ul><li><a href="#path包">path包</a></li><li><a href="#filepath包">filepath包</a></li></ul></li><li><a href="#异常和恢复">异常和恢复</a></li><li><a href="#http">HTTP</a></li><li><a href="#作业调度">作业调度</a></li><li><a href="#进程线程协程">进程线程协程</a><ul><li><a href="#进程">进程</a></li><li><a href="#协程">协程</a></li></ul></li><li><a href="#orm">ORM</a></li><li><a href="#daemon">Daemon</a></li></ul></div><p></p> <h2 id="flag"><a href="#flag" class="header-anchor">#</a> Flag</h2> <blockquote><p>go语言中的函数可以有多个返回值</p></blockquote> <blockquote><p>go语言是一种函数式编程语言，函数是go语言中的一等公民，函数的参数，返回值以及函数体内都可以存在函数</p></blockquote> <blockquote><p>go中的函数没有默认参数、可选参数也没有函数重载、操作符重载，但有可变参数列表，即（变量　...类型），此时类型钱的变量是一个此类型的数组</p></blockquote> <ul><li><a href="https://my.oschina.net/byonds/blog/488492" target="_blank" rel="noopener noreferrer">strconv包使用<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://www.jianshu.com/p/84bac7932394" target="_blank" rel="noopener noreferrer">runtime包<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://blog.csdn.net/TDCQZD/article/details/81835149" target="_blank" rel="noopener noreferrer">File操作<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <p><strong>日志</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>Logger<span class="token punctuation">)</span> <span class="token function">Log</span><span class="token punctuation">(</span>level Level<span class="token punctuation">,</span> format <span class="token builtin">string</span><span class="token punctuation">,</span> args <span class="token operator">...</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	l<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token keyword">defer</span> l<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 设置日志初始化参数</span>
	<span class="token comment">// log.Lshortfile 简要文件路径，log.Llongfile 完整文件路径</span>
	<span class="token comment">//log.SetFlags(log.Lshortfile | log.LstdFlags)</span>
	dbgLogger <span class="token operator">:=</span> log<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>l<span class="token punctuation">.</span>file<span class="token punctuation">,</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span> log<span class="token punctuation">.</span>Llongfile<span class="token operator">|</span>log<span class="token punctuation">.</span>LstdFlags<span class="token punctuation">)</span>
	<span class="token comment">// 传入0为获取当前行数,文件名,函数名(方法名)</span>
	funcName<span class="token punctuation">,</span> file<span class="token punctuation">,</span> line<span class="token punctuation">,</span> ok <span class="token operator">:=</span> runtime<span class="token punctuation">.</span><span class="token function">Caller</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
	<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span>
		file <span class="token operator">=</span> <span class="token string">&quot;???&quot;</span>
		line <span class="token operator">=</span> <span class="token number">0</span>
	<span class="token punctuation">}</span>
	info <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span>
		<span class="token string">&quot;[&quot;</span> <span class="token operator">+</span> <span class="token function">string</span><span class="token punctuation">(</span>level<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">&quot;]&quot;</span><span class="token punctuation">,</span>
		runtime<span class="token punctuation">.</span><span class="token function">FuncForPC</span><span class="token punctuation">(</span>funcName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Name</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		format<span class="token punctuation">,</span>
	<span class="token punctuation">}</span>
	dbgLogger<span class="token punctuation">.</span><span class="token function">Output</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> strings<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>info<span class="token punctuation">,</span> <span class="token string">&quot;.&quot;</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">&quot;\n&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>判断</strong></p> <ul><li>判断结构体是否为空</li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">if</span> reflect<span class="token punctuation">.</span><span class="token function">DeepEqual</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> A<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;a == A{} empty&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 括号不能去</span>
<span class="token keyword">if</span> a <span class="token operator">==</span> <span class="token punctuation">(</span>A<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;a == A{} empty&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>判断数组不能使用<code>a == nil</code>，应该使用<code>len(a) == 0</code></li></ul> <p><strong>默认值</strong></p> <ul><li>整型和浮点型变量的默认值为<code>0</code>。</li> <li>字符串变量的默认值为<code>&quot;&quot;</code>。</li> <li>布尔型<code>bool</code>默认值为<code>false</code>。</li> <li>指针、切片、字典、通道、接口、错误<code>error</code>的默认为<code>nil</code>。</li> <li>复数类型如<code>complex64</code>、<code>complex128</code>默认值为<code>0+0i</code>。</li> <li>数组的默认值要根据其数据类型来确定。 例如：<code>var a [4]int</code>，其默认值为<code>[0 0 0 0]</code></li></ul> <h2 id="字符串"><a href="#字符串" class="header-anchor">#</a> 字符串</h2> <ul><li><a href="https://blog.csdn.net/lsmsrc/article/details/104652533" target="_blank" rel="noopener noreferrer">高性能 golang 生成指定长度随机字符串<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/gohouse/random" target="_blank" rel="noopener noreferrer">https://github.com/gohouse/random<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h3 id="strings包api"><a href="#strings包api" class="header-anchor">#</a> strings包API</h3> <ul><li><code>strings.HasPrefix(s string, prefix string) bool</code>：判断字符串s是否以prefix开头</li> <li><code>strings.HasSuffix(s string, suffix string) bool</code>：判断字符串s是否以suffix结尾。</li> <li><code>strings.Index(s string, str string) int</code>：判断str在s中首次出现的位置，如果没有出现，则返回-1</li> <li><code>strings.LastIndex(s string, str string) int</code>：判断str在s中最后出现的位置，如果没有出现，则返回-1</li> <li><code>strings.Replace(str string, old string, new string, n int)</code>：字符串替换</li> <li><code>strings.Count(str string, substr string)int</code>：字符串计数</li> <li><code>strings.Repeat(str string, count int)string</code>：重复count次str</li> <li><code>strings.ToLower(str string)string</code>：转为小写</li> <li><code>strings.ToUpper(str string)string</code>：转为大写</li> <li><code>strings.TrimSpace(str string)</code>：去掉字符串首尾空白字符</li> <li><code>strings.Trim(str string, cut string)</code>：去掉字符串首尾cut字符</li> <li><code>strings.TrimLeft(str string, cut string)</code>：去掉字符串首cut字符</li> <li><code>strings.TrimRight(str string, cut string)</code>：去掉字符串首cut字符</li> <li><code>strings.Field(str string)</code>：返回str空格分隔的所有子串的slice</li> <li><code>strings.Split(str string, split string)</code>：返回str split分隔的所有子串的slice</li> <li><code>strings.Join(s1 []string, sep string)</code>：用sep把s1中的所有元素链接起来</li> <li><code>strings.Itoa(i int)</code>：把一个整数i转成字符串</li> <li><code>strings.Atoi(str string)(int, error)</code>：把一个字符串转成整数</li></ul> <h3 id="字符串拼接"><a href="#字符串拼接" class="header-anchor">#</a> 字符串拼接</h3> <ul><li><code>+</code> 连接适用于短小的、常量字符串（明确的，非变量），因为编译器会给我们优化。</li> <li><code>Join</code>是比较统一的拼接，不太灵活</li> <li><code>fmt</code>和<code>buffer</code>基本上不推荐</li> <li><code>builder</code>从性能和灵活性上，都是上佳的选择。</li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">StringPlus</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span><span class="token punctuation">{</span>
	<span class="token keyword">var</span> s <span class="token builtin">string</span>
	l<span class="token operator">:=</span><span class="token function">len</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span>
	<span class="token keyword">for</span> i<span class="token operator">:=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>l<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">{</span>
		s<span class="token operator">+=</span>p<span class="token punctuation">[</span>i<span class="token punctuation">]</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> s
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">StringFmt</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">string</span><span class="token punctuation">{</span>
	<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Sprint</span><span class="token punctuation">(</span>p<span class="token operator">...</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">StringJoin</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span><span class="token punctuation">{</span>
	<span class="token keyword">return</span> strings<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span><span class="token string">&quot;&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">StringBuffer</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> b bytes<span class="token punctuation">.</span>Buffer
	l<span class="token operator">:=</span><span class="token function">len</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span>
	<span class="token keyword">for</span> i<span class="token operator">:=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>l<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">{</span>
		b<span class="token punctuation">.</span><span class="token function">WriteString</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> b<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">StringBuilder</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> b strings<span class="token punctuation">.</span>Builder
	l<span class="token operator">:=</span><span class="token function">len</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span>
	<span class="token keyword">for</span> i<span class="token operator">:=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>l<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">{</span>
		b<span class="token punctuation">.</span><span class="token function">WriteString</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> b<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="io操作"><a href="#io操作" class="header-anchor">#</a> IO操作</h2> <blockquote><p>Go标准库中还有<code>path</code>和<code>path/filepath</code>函数有点重复,大部分情况下建议使用<code>path/filepath</code></p></blockquote> <blockquote><p>两者区别是：<code>path</code>使用<code>/</code>作为路径分隔符，<code>path/filepath</code>判断系统使用不同的路径分隔符</p></blockquote> <p><strong>从 Go 1.16 开始会废弃 io/ioutil 包，相关的功能会挪到 io 包或 os 包</strong></p> <ul><li><a href="https://github.com/golang/go/issues/40025" target="_blank" rel="noopener noreferrer">https://github.com/golang/go/issues/40025<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/golang/go/issues/42026" target="_blank" rel="noopener noreferrer">https://github.com/golang/go/issues/42026<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h3 id="path包"><a href="#path包" class="header-anchor">#</a> path包</h3> <table><thead><tr><th>函数</th> <th>说明</th></tr></thead> <tbody><tr><td>IsAbs(path string) bool</td> <td>判断是否是一个绝对路径</td></tr> <tr><td>Split(path string) (dir, file string)</td> <td>将路径分割为路径和文件名</td></tr> <tr><td>Join(elem ...string) string</td> <td>将多个字符串合并为一个路径</td></tr> <tr><td>Ext(path string) string</td> <td>返回路径中扩展部分</td></tr> <tr><td>Base(path string) string</td> <td>返回路径的最后一个元素</td></tr> <tr><td>Dir(path string) string</td> <td>返回路径中目录部分</td></tr> <tr><td>Clean(path string) string</td> <td>返回同目录的最短路径</td></tr> <tr><td>Match(pattern, name string) (matched bool, err error)</td> <td>正则是否匹配路径（shell 文件名匹配）</td></tr></tbody></table> <h3 id="filepath包"><a href="#filepath包" class="header-anchor">#</a> filepath包</h3> <table><thead><tr><th>函数</th> <th>说明</th></tr></thead> <tbody><tr><td>filepath.ListSeparator</td> <td>预定义变量，表示环境变量分隔符 :</td></tr> <tr><td>filepath.Separator</td> <td>预定义变量，表示路径分隔符/</td></tr> <tr><td>Abs(path string) (string, error)</td> <td>返回path 相对当前路径的绝对路径</td></tr> <tr><td>Base(path string) string</td> <td>返回路径最后一个元素</td></tr> <tr><td>Clean(path string) string</td> <td>返回path 的最短路径</td></tr> <tr><td>Dir(path string) string</td> <td>返回路径最后一个元素的目录</td></tr> <tr><td>EvalSymlinks(path string) (string, error)</td> <td>返回软链指向的路径</td></tr> <tr><td>Ext(path string) string</td> <td>返回路径中的扩展名，如果没有点返回空</td></tr> <tr><td>FromSlash(path string) string</td> <td>/替换为路径分隔符</td></tr> <tr><td>Join(elem ...string) string</td> <td>连接路径，返回已经clean过的路径</td></tr> <tr><td>Rel(basepath, targpath string) (string, error)</td> <td>返回targpath 相对 basepath路径</td></tr> <tr><td>Split(path string) (dir, file string)</td> <td>分割路径中的目录与文件</td></tr> <tr><td>SplitList(path string) []string</td> <td>分隔环境变量里面的路径</td></tr> <tr><td>ToSlash(path string) string</td> <td>路径分隔符替换为/</td></tr> <tr><td>VolumeName(path string) string</td> <td>返回路径最前面的卷名</td></tr> <tr><td>Walk(root string, walkFn WalkFunc) error</td> <td>遍历 root 目录下的文件树，并调用 walkFn</td></tr> <tr><td>Glob(pattern string) (matches []string, err error)</td> <td>返回所有匹配的文件</td></tr> <tr><td>IsAbs(path string) (b bool)</td> <td>判断路径是不是绝对路径</td></tr> <tr><td>Match(pattern, name string) (matched bool, err error)</td> <td>匹配文件名，完全匹配则返回true</td></tr></tbody></table> <h2 id="异常和恢复"><a href="#异常和恢复" class="header-anchor">#</a> 异常和恢复</h2> <blockquote><p>Go语言追求简洁优雅，所以，Go语言不支持传统的<code>try…catch…finally</code> 这种异常，因为Go语言的设计者们认为，
将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常，甚至一个小小的错误都抛出一个异常。</p></blockquote> <blockquote><p>在Go语言中，使用多值返回来返回错误。不要用异常代替错误，更不要用来控制流程。在极个别的情况下，
才使用Go中引入的<code>Exception</code>处理：<code>defer</code>、<code>panic</code>、<code>recover</code>。</p></blockquote> <p><strong>panic</strong></p> <blockquote><p>函数中书写了<code>panic</code>语句，会终止其后要执行的代码，直到<code>goroutine</code>整个退出，并报告错误</p></blockquote> <blockquote><p>如果在<code>panic</code>函数之前存在<code>defer</code>函数，则执行<code>defer</code>函数，这里的<code>defer</code>有点类似<code>try…catch…finally</code>中的<code>finally</code>，</p> <blockquote><p>如果<code>defer</code>函数内不包含<code>recover</code>会直到<code>goroutine</code>整个退出，并报告错误</p> <p>相反则会捕获这个<code>panic</code>类似于<code>try…catch…finally</code>中的<code>catch</code></p></blockquote></blockquote> <p><strong>defer</strong></p> <blockquote><p>可以将一个方法延迟到包裹该方法的方法返回时执行，<code>defer</code>语句可以充当其他语言中<code>try…catch…finally</code>的角色，
也可以用来处理关闭文件句柄等收尾操作。</p></blockquote> <ol><li>包裹<code>defer</code>的函数返回时</li> <li>包裹<code>defer</code>的函数执行到末尾时</li> <li>所在的<code>goroutine</code>发生<code>panic</code>时</li></ol> <blockquote><p>当一个方法中有多个<code>defer</code>时，<code>defer</code>会将要延迟执行的方法<code>压栈</code>，当<code>defer</code>被触发时，将所有<code>压栈</code>的方法<code>出栈</code>并执行。
所以<code>defer</code>的执行顺序是<code>LIFO</code>(后进先出)的。</p></blockquote> <p><strong>recover</strong></p> <ol><li>用来控制一个<code>goroutine</code>的<code>panicking</code>行为，捕获<code>panic</code>，从而影响应用的行为</li></ol> <blockquote><p>在<code>defer</code>函数中，通过<code>recever</code>来终止一个<code>goroutine</code>的<code>panicking</code>过程，从而恢复正常代码的执行，可以获取通过<code>panic</code>传递的<code>error</code></p></blockquote> <p><strong>简单来讲：可以抛出一个<code>panic</code>的异常，然后在<code>defer</code>中通过<code>recover</code>捕获这个异常，然后正常处理。</strong></p> <p><strong>注意：利用<code>recover</code>处理<code>panic</code>指令，<code>defer</code>必须在<code>panic</code>之前声明，否则<code>recover</code>无法捕获到<code>panic</code></strong></p> <p><strong>示例</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;++++++++++++++++++++&quot;</span><span class="token punctuation">)</span>
	<span class="token comment">// 必须要先声明defer，否则不能捕获到panic异常</span>
	<span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;=============&quot;</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> <span class="token function">recover</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			<span class="token comment">// 这里的err其实就是panic传入的内容</span>
			fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
		fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;=============&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 开始调用test</span>
	<span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 这里开始下面代码不会再执行</span>
	fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;+++++++++++++++++++&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;*******************&quot;</span><span class="token punctuation">)</span>
	<span class="token function">panic</span><span class="token punctuation">(</span><span class="token string">&quot;异常信息&quot;</span><span class="token punctuation">)</span>
	<span class="token comment">//这里开始下面代码不会再执行</span>
	fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;b&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="http"><a href="#http" class="header-anchor">#</a> HTTP</h2> <ul><li><a href="https://www.jianshu.com/p/2ecda118336f" target="_blank" rel="noopener noreferrer">关于golang 的readall清空reader<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://my.oschina.net/bianweiall/blog/544355" target="_blank" rel="noopener noreferrer">multipart/form-data POST上传文件<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="http://hacktech.cn/2017/07/07/Golang%E6%A8%A1%E6%8B%9F%E5%AE%A2%E6%88%B7%E7%AB%AFPOST%E8%A1%A8%E5%8D%95%E5%8A%9F%E8%83%BD%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0.html" target="_blank" rel="noopener noreferrer">Golang模拟客户端POST表单功能文件上传<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://1024coder.com/14845548548981.html" target="_blank" rel="noopener noreferrer">go语言模拟multipart/form-data提交数据<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/xuanbo/requests" target="_blank" rel="noopener noreferrer">https://github.com/xuanbo/requests<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://zhuanlan.zhihu.com/p/96491484" target="_blank" rel="noopener noreferrer">从 HTTP 角度看 Go 如何实现文件上传<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">var</span> buffer <span class="token punctuation">[</span><span class="token number">512</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
result <span class="token operator">:=</span> bytes<span class="token punctuation">.</span><span class="token function">NewBuffer</span><span class="token punctuation">(</span><span class="token boolean">nil</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
    n<span class="token punctuation">,</span> err <span class="token operator">:=</span> resp<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span>buffer<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    result<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span>buffer<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span>n<span class="token punctuation">]</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> err <span class="token operator">==</span> io<span class="token punctuation">.</span>EOF <span class="token punctuation">{</span>
        <span class="token keyword">break</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
        <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//result, _ := ioutil.ReadAll(resp.Body)</span>
<span class="token comment">// 必须关闭</span>
<span class="token keyword">defer</span> resp<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// 使用ioutil.ReadAll 会清空对应Reader，重新赋值对应Reader</span>
<span class="token comment">//resp.Body = ioutil.NopCloser(bytes.NewBuffer(result))</span>

<span class="token comment">// 解析参数，填充到Form、PostForm，这里也会清空对应Reader</span>
resp<span class="token punctuation">.</span>Request<span class="token punctuation">.</span><span class="token function">ParseForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// 解析文件上传表单的post参数</span>
resp<span class="token punctuation">.</span>Request<span class="token punctuation">.</span><span class="token function">ParseMultipartForm</span><span class="token punctuation">(</span><span class="token number">1024</span><span class="token punctuation">)</span>
</code></pre></div><div class="language-go extra-class"><pre class="language-go"><code><span class="token comment">// http.Client发送请求，此方式是封装的http.NewRequest方法</span>
<span class="token comment">//</span>
<span class="token comment">// method:	请求方法：POST、GET、PUT、DELETE</span>
<span class="token comment">// urlText:		请求地址</span>
<span class="token comment">// contentType: 请求数据类型，首字母简写，如：axwfu</span>
<span class="token comment">// params:	请求参数</span>
<span class="token keyword">func</span> <span class="token function">HttpClient</span><span class="token punctuation">(</span>method<span class="token punctuation">,</span> urlText<span class="token punctuation">,</span> contentType <span class="token builtin">string</span><span class="token punctuation">,</span> params <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>http<span class="token punctuation">.</span>Response<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">if</span> urlText <span class="token operator">==</span> <span class="token string">&quot;&quot;</span> <span class="token punctuation">{</span>
		<span class="token function">panic</span><span class="token punctuation">(</span>errors<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">&quot;url不能为空&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	client <span class="token operator">:=</span> http<span class="token punctuation">.</span>Client<span class="token punctuation">{</span>Timeout<span class="token punctuation">:</span> <span class="token number">30</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">}</span>

	<span class="token keyword">var</span> resp <span class="token operator">*</span>http<span class="token punctuation">.</span>Response
	<span class="token keyword">var</span> err <span class="token builtin">error</span>

	method <span class="token operator">=</span> strings<span class="token punctuation">.</span><span class="token function">ToUpper</span><span class="token punctuation">(</span>method<span class="token punctuation">)</span>
	<span class="token keyword">if</span> method <span class="token operator">==</span> http<span class="token punctuation">.</span>MethodPost <span class="token operator">||</span> method <span class="token operator">==</span> http<span class="token punctuation">.</span>MethodPatch <span class="token operator">||</span> method <span class="token operator">==</span> http<span class="token punctuation">.</span>MethodPut <span class="token punctuation">{</span>
		<span class="token keyword">if</span> params <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			<span class="token keyword">switch</span> contentType <span class="token punctuation">{</span>
			<span class="token keyword">case</span> <span class="token string">&quot;axwfu&quot;</span><span class="token punctuation">:</span> <span class="token comment">// application/x-www-form-urlencoded</span>
				data <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span>url<span class="token punctuation">.</span>Values<span class="token punctuation">)</span>
				<span class="token comment">//data := url.Values{}</span>
				<span class="token keyword">for</span> k<span class="token punctuation">,</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> params <span class="token punctuation">{</span>
					data<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span>v<span class="token punctuation">}</span>
					<span class="token comment">//data.Set(k, v)</span>
				<span class="token punctuation">}</span>
				resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span>urlText<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
			<span class="token keyword">case</span> <span class="token string">&quot;mf&quot;</span><span class="token punctuation">:</span> <span class="token comment">// multipart/form-data</span>
				bodyBuf <span class="token operator">:=</span> <span class="token operator">&amp;</span>bytes<span class="token punctuation">.</span>Buffer<span class="token punctuation">{</span><span class="token punctuation">}</span>
                writer <span class="token operator">:=</span> multipart<span class="token punctuation">.</span><span class="token function">NewWriter</span><span class="token punctuation">(</span>bodyBuf<span class="token punctuation">)</span>
                <span class="token keyword">for</span> k<span class="token punctuation">,</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> params <span class="token punctuation">{</span>
                    <span class="token keyword">if</span> err <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">WriteField</span><span class="token punctuation">(</span>k<span class="token punctuation">,</span> v<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
                        <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> err <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
                    <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
                <span class="token punctuation">}</span>
				resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span>urlText<span class="token punctuation">,</span> writer<span class="token punctuation">.</span><span class="token function">FormDataContentType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> bodyBuf<span class="token punctuation">)</span>
			<span class="token keyword">case</span> <span class="token string">&quot;tx&quot;</span><span class="token punctuation">:</span> <span class="token comment">// text/xml</span>
				jsonStr<span class="token punctuation">,</span> err <span class="token operator">:=</span> json<span class="token punctuation">.</span><span class="token function">Marshal</span><span class="token punctuation">(</span>params<span class="token punctuation">)</span>
				<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
					<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
				<span class="token punctuation">}</span>
				data <span class="token operator">:=</span> strings<span class="token punctuation">.</span><span class="token function">ReplaceAll</span><span class="token punctuation">(</span><span class="token function">string</span><span class="token punctuation">(</span>jsonStr<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&quot; &quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;+&quot;</span><span class="token punctuation">)</span>
				resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span>urlText<span class="token punctuation">,</span> contentType<span class="token punctuation">,</span> bytes<span class="token punctuation">.</span><span class="token function">NewBuffer</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
			<span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token comment">// application/json</span>
				jsonStr<span class="token punctuation">,</span> err <span class="token operator">:=</span> json<span class="token punctuation">.</span><span class="token function">Marshal</span><span class="token punctuation">(</span>params<span class="token punctuation">)</span>
				<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
					<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
				<span class="token punctuation">}</span>
				resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span>urlText<span class="token punctuation">,</span> <span class="token string">&quot;application/json&quot;</span><span class="token punctuation">,</span> bytes<span class="token punctuation">.</span><span class="token function">NewBuffer</span><span class="token punctuation">(</span>jsonStr<span class="token punctuation">)</span><span class="token punctuation">)</span>
			<span class="token punctuation">}</span>
		<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
			resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span>urlText<span class="token punctuation">,</span> contentType<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
		<span class="token keyword">if</span> params <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			urlText <span class="token operator">=</span> urlText <span class="token operator">+</span> <span class="token string">&quot;?&quot;</span>
			<span class="token keyword">for</span> key<span class="token punctuation">,</span> value <span class="token operator">:=</span> <span class="token keyword">range</span> params <span class="token punctuation">{</span>
				urlText <span class="token operator">+=</span> key <span class="token operator">+</span> <span class="token string">&quot;=&quot;</span> <span class="token operator">+</span> value <span class="token operator">+</span> <span class="token string">&quot;&amp;&quot;</span>
			<span class="token punctuation">}</span>
		<span class="token punctuation">}</span>
		<span class="token comment">// url编码</span>
		<span class="token comment">//urlText=urlText.QueryEscape(urlText)</span>
		<span class="token keyword">if</span> method <span class="token operator">==</span> <span class="token string">&quot;HEAD&quot;</span> <span class="token punctuation">{</span>
			resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Head</span><span class="token punctuation">(</span>urlText<span class="token punctuation">)</span>
		<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
			resp<span class="token punctuation">,</span> err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>urlText<span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> resp<span class="token punctuation">,</span> err
<span class="token punctuation">}</span>
</code></pre></div><h2 id="作业调度"><a href="#作业调度" class="header-anchor">#</a> 作业调度</h2> <ul><li><code>ticker</code>只要定义完成，从此刻开始计时，不需要任何其他的操作，每隔固定时间都会触发。</li> <li><code>timer</code>定时器，是到固定时间后会执行一次</li></ul> <blockquote><p>如果timer定时器要每隔间隔的时间执行，实现ticker的效果，使用 func (t *Timer) Reset(d Duration) bool</p></blockquote> <ul><li><a href="https://learnku.com/articles/23578/the-difference-between-go-timer-and-ticker" target="_blank" rel="noopener noreferrer">go timer 和 ticker 的区别<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <p><strong>固定到每天的Duration</strong></p> <div class="language-go extra-class"><pre class="language-go"><code>now <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// 计算下一个时间点</span>
next <span class="token operator">:=</span> now<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
next <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">Date</span><span class="token punctuation">(</span>next<span class="token punctuation">.</span><span class="token function">Year</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> next<span class="token punctuation">.</span><span class="token function">Month</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> next<span class="token punctuation">.</span><span class="token function">Day</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> next<span class="token punctuation">.</span><span class="token function">Location</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> next<span class="token punctuation">.</span><span class="token function">Sub</span><span class="token punctuation">(</span>now<span class="token punctuation">)</span> <span class="token operator">&lt;=</span> <span class="token number">0</span> <span class="token punctuation">{</span>
    next <span class="token operator">=</span> next<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Hour <span class="token operator">*</span> <span class="token number">24</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
ticker <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTicker</span><span class="token punctuation">(</span>next<span class="token punctuation">.</span><span class="token function">Sub</span><span class="token punctuation">(</span>now<span class="token punctuation">)</span><span class="token punctuation">)</span>
timer <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTimer</span><span class="token punctuation">(</span>next<span class="token punctuation">.</span><span class="token function">Sub</span><span class="token punctuation">(</span>now<span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>Ticker</strong></p> <blockquote><p>ticker只要定义完成，从此刻开始计时，不需要任何其他的操作，每隔固定时间都会触发。</p></blockquote> <blockquote><p>NewTicker返回一个新的 Ticker，该 Ticker 包含一个通道字段，并会每隔时间段 d 就向该通道发送当时的时间。它会调<br>
整时间间隔或者丢弃 tick 信息以适应反应慢的接收者。如果d &lt;= 0会触发panic。关闭该 Ticker 可以释放相关资源</p></blockquote> <div class="language-go extra-class"><pre class="language-go"><code><span class="token comment">// 启动的时候执行一次，滚动间隔时间执行</span>
<span class="token keyword">func</span> <span class="token function">SchedulerIntervalsTicker</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 创建一个 Timer，它会在最少过去时间段 d后到期，向其自身的 C 字段发送当时的时间</span>
    ticker <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTicker</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
	<span class="token keyword">for</span> <span class="token punctuation">{</span>
		<span class="token keyword">go</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token operator">&lt;-</span>ticker<span class="token punctuation">.</span>C
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">SchedulerIntervalsTicker</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> ch <span class="token keyword">chan</span> <span class="token builtin">int</span>
	<span class="token comment">// 定时任务</span>
	ticker <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTicker</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
	<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">for</span> <span class="token keyword">range</span> ticker<span class="token punctuation">.</span>C <span class="token punctuation">{</span>
			<span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
		ch <span class="token operator">&lt;-</span> <span class="token number">1</span>
	<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token operator">&lt;-</span>ch
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">SchedulerIntervalsTicker</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 定时任务</span>
	ticker <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTicker</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
	<span class="token keyword">for</span> <span class="token keyword">range</span> ticker<span class="token punctuation">.</span>C <span class="token punctuation">{</span>
		<span class="token keyword">go</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>Timer</strong></p> <blockquote><p><code>timer</code>定时器，是到固定时间后会执行一次，它会在最少过去时间段 d 后到期，向其自身的 C 字段发送当时的时间</p></blockquote> <div class="language-go extra-class"><pre class="language-go"><code><span class="token comment">// 启动的时候执行一次</span>
<span class="token keyword">func</span> <span class="token function">SchedulerFixedTimer</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    timer <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTimer</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
    <span class="token keyword">for</span> <span class="token punctuation">{</span>
        <span class="token keyword">go</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token operator">&lt;-</span>timer<span class="token punctuation">.</span>C
        <span class="token comment">// Reset 使 ticker 重新开始计时，否则会导致通道堵塞，（本方法返回后再）等待时间段 d 过去后到期。</span>
        <span class="token comment">// 如果调用时t还在等待中会返回真；如果 t已经到期或者被停止了会返回假</span>
        timer<span class="token punctuation">.</span><span class="token function">Reset</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">SchedulerFixedTimer</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	timer <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTimer</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
	<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">for</span> <span class="token keyword">range</span> timer<span class="token punctuation">.</span>C <span class="token punctuation">{</span>
			<span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
		ch <span class="token operator">&lt;-</span> <span class="token number">1</span>
	<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token operator">&lt;-</span>ch
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">SchedulerFixedTimer</span><span class="token punctuation">(</span>f <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> duration time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	timer <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTimer</span><span class="token punctuation">(</span>duration<span class="token punctuation">)</span>
	<span class="token keyword">for</span> <span class="token keyword">range</span> timer<span class="token punctuation">.</span>C <span class="token punctuation">{</span>
		<span class="token keyword">go</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="进程线程协程"><a href="#进程线程协程" class="header-anchor">#</a> 进程线程协程</h2> <blockquote><p>GO程序是单进程的（手动<code>fork/exec</code>不算），但是调度器是多线程的。</p></blockquote> <ul><li><a href="https://segmentfault.com/q/1010000007372739" target="_blank" rel="noopener noreferrer">go 开多个goroutine，是在一个进程中完成，还是可能在多个进程中完成<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://chierqj.github.io/golang-duo-jin-cheng-bing-fa" target="_blank" rel="noopener noreferrer">golang多进程并发<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h3 id="进程"><a href="#进程" class="header-anchor">#</a> 进程</h3> <blockquote><p><code>exec</code>包执行外部命令，它将<code>os.StartProcess</code>进行包装使得它更容易映射到<code>stdin</code>和<code>stdout</code>，并且利用<code>pipe</code>连接<code>i/o</code></p></blockquote> <blockquote><p>这和<code>python``下的command</code>、<code>os.system</code>等功能一样。可以调用类<code>LINUX</code>系统下的<code>shell</code>命令，也可以在<code>windows</code>下调用<code>cmd</code>命令。</p></blockquote> <blockquote><p>os包中实现了平台无关的接口，设计向Unix风格，但是错误处理是go风格，当os包使用时，如果失败之后返回错误类型而不是错误数量．</p></blockquote> <ul><li><a href="https://blog.csdn.net/chenbaoke/article/details/42494851" target="_blank" rel="noopener noreferrer">golang中os包用法<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <div class="language-go extra-class"><pre class="language-go"><code>proc<span class="token punctuation">,</span> err <span class="token operator">=</span> os<span class="token punctuation">.</span><span class="token function">StartProcess</span><span class="token punctuation">(</span><span class="token string">&quot;test.exe&quot;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>os<span class="token punctuation">.</span>ProcAttr<span class="token punctuation">{</span>Files<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>os<span class="token punctuation">.</span>File<span class="token punctuation">{</span>os<span class="token punctuation">.</span>Stdin<span class="token punctuation">,</span> os<span class="token punctuation">.</span>Stdout<span class="token punctuation">,</span> os<span class="token punctuation">.</span>Stderr<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="协程"><a href="#协程" class="header-anchor">#</a> 协程</h3> <ul><li><a href="https://www.jianshu.com/p/c3d65105fa46" target="_blank" rel="noopener noreferrer">多线程<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://blog.csdn.net/sun_hongtao/article/details/76972156" target="_blank" rel="noopener noreferrer">Go 并发 、并行、线程池<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://blog.csdn.net/ytd7777/article/details/85004371" target="_blank" rel="noopener noreferrer">多线程 并发<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://segmentfault.com/a/1190000019229973" target="_blank" rel="noopener noreferrer">Go 并发控制<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://blog.csdn.net/github_37320188/article/details/93909877" target="_blank" rel="noopener noreferrer">多任务线程池并发<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://studygolang.com/articles/17944" target="_blank" rel="noopener noreferrer">深度剖析 Go 中的 Go 协程 (goroutines) -- Go 的并发<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">go</span> 函数
</code></pre></div><ul><li>匿名<code>Go</code>协程</li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 业务逻辑</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><ul><li>协程的调度</li></ul> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">TestGorutine</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 指定最大 P 为 1，从而管理协程最多的线程为 1 个    </span>
    runtime<span class="token punctuation">.</span><span class="token function">GOMAXPROCS</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token comment">// 显式地让出CPU时间给其他goroutine</span>
    <span class="token comment">//runtime.Gosched()</span>
    <span class="token comment">// 控制等待所有协程都执行完再退出程序    </span>
    wg <span class="token operator">:=</span> sync<span class="token punctuation">.</span>WaitGroup<span class="token punctuation">{</span><span class="token punctuation">}</span>
    wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
    <span class="token comment">// 运行一个协程</span>
    <span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
        wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment">// 运行第二个协程</span>
    <span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">65</span><span class="token punctuation">)</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">66</span><span class="token punctuation">)</span>
        <span class="token comment">// 设置个睡眠，让该协程执行超时而被挂起，引起超时调度</span>
        time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token number">67</span><span class="token punctuation">)</span>
        wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="orm"><a href="#orm" class="header-anchor">#</a> ORM</h2> <blockquote><p><code>Object-Relational Mapping</code>，把关系数据库的表结构映射到对象上。</p></blockquote> <ul><li><a href="https://segmentfault.com/a/1190000015606291" target="_blank" rel="noopener noreferrer">orm对比<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <ul><li><a href="https://github.com/jmoiron/sqlx" target="_blank" rel="noopener noreferrer">https://github.com/jmoiron/sqlx<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/jinzhu/gorm" target="_blank" rel="noopener noreferrer">https://github.com/jinzhu/gorm<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/go-xorm/xorm" target="_blank" rel="noopener noreferrer">https://github.com/go-xorm/xorm<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/gohouse/gorose" target="_blank" rel="noopener noreferrer">https://github.com/gohouse/gorose<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/go-gorp/gorp" target="_blank" rel="noopener noreferrer">https://github.com/go-gorp/gorp<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h2 id="daemon"><a href="#daemon" class="header-anchor">#</a> Daemon</h2> <ul><li><a href="https://en.wikipedia.org/wiki/Daemon_(computing)" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Daemon_(computing)<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <blockquote><p>在一个多任务的电脑操作系统中，Daemon（守护进程）是一种在后台执行的电脑程序。此类程序会被以进程的形式初始化</p></blockquote> <blockquote><p>通常，守护进程没有任何存在的父进程（即PPID=1），且在UNIX系统进程层级中直接位于init之下。
守护进程程序通常通过如下方法使自己成为守护进程：对一个子进程运行fork，然后使其父进程立即终止，
使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。</p></blockquote> <ul><li><a href="https://github.com/topics/daemon" target="_blank" rel="noopener noreferrer">https://github.com/topics/daemon<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/takama/daemon" target="_blank" rel="noopener noreferrer">https://github.com/takama/daemon<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/ochinchina/supervisord" target="_blank" rel="noopener noreferrer">https://github.com/ochinchina/supervisord<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <ul><li>几种实现方式</li></ul> <ol><li>nohup</li> <li>supervise</li> <li>Cgo deamon函数</li> <li>go通过syscall调用fork实现(这个和第3条原理一样)</li></ol> <p><strong>Cgo实现</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">&quot;fmt&quot;</span>
    <span class="token string">&quot;net&quot;</span>
    <span class="token string">&quot;runtime&quot;</span>
<span class="token punctuation">)</span>

<span class="token comment">/*
#include &lt;unistd.h&gt;
*/</span>
<span class="token keyword">import</span> <span class="token string">&quot;C&quot;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 守护进程</span>
    C<span class="token punctuation">.</span><span class="token function">daemon</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
    runtime<span class="token punctuation">.</span><span class="token function">GOMAXPROCS</span><span class="token punctuation">(</span>runtime<span class="token punctuation">.</span><span class="token function">NumCPU</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Starting the server ...&quot;</span><span class="token punctuation">)</span>
    listener<span class="token punctuation">,</span> err <span class="token operator">:=</span> net<span class="token punctuation">.</span><span class="token function">Listen</span><span class="token punctuation">(</span><span class="token string">&quot;tcp&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;localhost:8080&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Error listening&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">for</span> <span class="token punctuation">{</span>
        conn<span class="token punctuation">,</span> err <span class="token operator">:=</span> listener<span class="token punctuation">.</span><span class="token function">Accept</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
            fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;error accepting&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">go</span> <span class="token function">doServerStuff</span><span class="token punctuation">(</span>conn<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">doServerStuff</span><span class="token punctuation">(</span>conn net<span class="token punctuation">.</span>Conn<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">{</span>
        buf <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token number">512</span><span class="token punctuation">)</span>
        <span class="token boolean">_</span><span class="token punctuation">,</span> err <span class="token operator">:=</span> conn<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span>
        <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
            fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Error reading&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span>
        <span class="token punctuation">}</span>
        fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;Received data: %v&quot;</span><span class="token punctuation">,</span> <span class="token function">string</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>支持goroutine和系统信号监听</strong></p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">package</span> main
 
<span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">&quot;os&quot;</span>
    <span class="token string">&quot;fmt&quot;</span>
    <span class="token string">&quot;os/signal&quot;</span>
    <span class="token string">&quot;syscall&quot;</span>
    <span class="token string">&quot;time&quot;</span>
    <span class="token string">&quot;log&quot;</span>
    <span class="token string">&quot;os/exec&quot;</span>
<span class="token punctuation">)</span>
<span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> os<span class="token punctuation">.</span><span class="token function">Getppid</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">1</span><span class="token punctuation">{</span>
        cmd <span class="token operator">:=</span> exec<span class="token punctuation">.</span><span class="token function">Command</span><span class="token punctuation">(</span>os<span class="token punctuation">.</span>Args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> os<span class="token punctuation">.</span>Args<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token operator">...</span><span class="token punctuation">)</span>
        cmd<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        os<span class="token punctuation">.</span><span class="token function">Exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
 
    <span class="token comment">// 监听系统信号</span>
    <span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        _c <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> os<span class="token punctuation">.</span>Signal<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
        signal<span class="token punctuation">.</span><span class="token function">Notify</span><span class="token punctuation">(</span>_c<span class="token punctuation">,</span> os<span class="token punctuation">.</span>Interrupt<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGHUP<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGINT<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGTERM<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGQUIT<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGKILL<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGTSTP<span class="token punctuation">)</span>
        msg <span class="token operator">:=</span> <span class="token operator">&lt;-</span> _c
        log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span>
        os<span class="token punctuation">.</span><span class="token function">Exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
 
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
 
    <span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        fp<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> os<span class="token punctuation">.</span><span class="token function">OpenFile</span><span class="token punctuation">(</span><span class="token string">&quot;log&quot;</span><span class="token punctuation">,</span> os<span class="token punctuation">.</span>O_WRONLY<span class="token operator">|</span>os<span class="token punctuation">.</span>O_CREATE<span class="token operator">|</span>os<span class="token punctuation">.</span>O_APPEND<span class="token punctuation">,</span> <span class="token number">0644</span><span class="token punctuation">)</span>
        log<span class="token punctuation">.</span><span class="token function">SetOutput</span><span class="token punctuation">(</span>fp<span class="token punctuation">)</span>
        <span class="token keyword">for</span><span class="token punctuation">{</span>
            log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>fmt<span class="token punctuation">.</span><span class="token function">Sprint</span><span class="token punctuation">(</span><span class="token string">&quot;hello &quot;</span><span class="token punctuation">,</span> os<span class="token punctuation">.</span><span class="token function">Getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second <span class="token operator">*</span> <span class="token number">5</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
 
    <span class="token keyword">for</span><span class="token punctuation">{</span>
        time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
 
<span class="token punctuation">}</span>
</code></pre></div></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/woytu/notes-vuepress/edit/master//Form/Go笔记.md" target="_blank" rel="noopener noreferrer">在 GitHub 上编辑此页</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/Form/Go爬虫.html" class="prev">
        Go爬虫
      </a></span> <span class="next"><a href="/Form/Go编译打包.html">
        Go编译打包
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    <script src="/assets/js/app.269009d6.js" defer></script><script src="/assets/js/3.974b9720.js" defer></script><script src="/assets/js/10.5915e99b.js" defer></script>
  </body>
</html>
